#include "Storage.h"
#include <winsock2.h>
#include <iostream>
#include <mysql.h>
#include <time.h>
#include <vector>
#include "General.h"
using namespace std;

General* general = new General();

/*
 * 将访问数据库所用到的变量都声明为全局变量
 */
MYSQL mysql;
MYSQL_RES* res;
MYSQL_ROW row;
char* sql = NULL;
General* _general = new General();

// 数据库Member表和Card表中最大的编号，用于在插入新的数据项（最大值+1）
int max_member_id;
int max_card_id;

Storage* Storage::instance_ = NULL;

void initDB();

bool query(char* sql) {
    if (mysql_real_query(&mysql, sql, strlen(sql)) != 0)
    {
        cerr << "mysql_real_query: "  << mysql_error(&mysql)  << endl;
        mysql_close(&mysql);
        return false;
    }
    // ´æ´¢½á¹û¼¯
    res = mysql_store_result(&mysql);
    if (NULL == res)
    {
        cerr << "mysql_store_result: "  << mysql_error(&mysql)  << endl;
        mysql_close(&mysql);
        return false;
    }
    return true;
}

bool insert(char* sql) {
    if (mysql_query(&mysql, sql) != 0) {
        cerr << "mysql_query: " << mysql_error(&mysql) << endl;
        mysql_close(&mysql);
        return false;
    }
    return true;
}

bool connectMysql() {
    mysql_init(&mysql);
    if (!mysql_real_connect(&mysql, "127.0.0.1", "testuser", "testuser123", "testdb", 3306, 0, 0))
    {
        cerr << "mysql_real_connect: "  << mysql_error(&mysql)  << endl ;
        return 0;
    }

    if (mysql_set_character_set(&mysql, "gbk") != 0)
    {
        cerr << "mysql_set_character_set: "  << mysql_error(&mysql)  << endl ;
        return 0;
    }
}

Storage::Storage()
{
}

Storage* Storage::getInstance(void) {
    initDB();
    if (instance_ == NULL)
        instance_ = new Storage;
    return instance_;
}

bool Storage::addMember(Member& member) {
    member.setMemberId(max_member_id++);
    connectMysql();
    string str = "insert into  member (ID, NAME, ADDRESS, JOB, CARD_NUM) value (" + general->toStr(member.getMemberId())
        + ",'" + member.getMemberName() + "','" + member.getAddress() + "','" + member.getJob() + "',-1)";
    sql = const_cast<char*>(str.data());
    if (!insert(sql))
        return false;
    return true;
}
bool Storage::addCard(Card& card) {
    card.setCardId(max_card_id++);
    connectMysql();
    string str = "select id from member where name = '" + card.getOwner() + "'";
    sql = const_cast<char*>(str.data());
    query(sql);

    vector<int> toSetIdList;
    int toSetIndex;
    while (row = mysql_fetch_row(res))
    {
        toSetIdList.push_back(_general->toInt(row[0]));
    }
    if (toSetIdList.empty())
        return false;

    if (toSetIdList.size() == 1) {
        toSetIndex = toSetIdList[0];
        string str = "update member  set card_num = " + _general->toStr(card.getType()) + " where id = " +
                      _general->toStr(toSetIdList[0]);
        sql = const_cast<char*>(str.data());
        mysql_query(&mysql, sql);
    } else {
        /*
        cout << "下列会员编号对应的名字都叫：" << arr[2] << "，请选择下列会员编号的序号：" << endl;
        for (int _toSetIndex = 0; _toSetIndex < toSetIdList.size(); _toSetIndex++) {
            cout << _toSetIndex+1 << ": " << format(toSetIdList[_toSetIndex]) << endl;
        }
        cin >> toSetIndex;
        */
        toSetIndex = toSetIdList[0];
        if (toSetIndex < 1 || toSetIndex > toSetIdList.size())
            return false;

        string str = "update member  set card_num = " + _general->toStr(card.getType()) + " where id = " +
                      _general->toStr(toSetIdList[toSetIndex-1]);
        sql = const_cast<char*>(str.data());
        mysql_query(&mysql, sql);
    }


    const time_t t = time(NULL);
    //本地时间：日期，时间 年月日，星期，时分秒
    struct tm* current_time = localtime(&t);

    string date = _general->toStr(1900+current_time->tm_year) + "-" + _general->toStr(1+current_time->tm_mon)
                  + "-" + _general->toStr(current_time->tm_mday);
    str = "insert into  card (ID, DATE, TIMES, PRICE, TYPE) value (" + _general->toStr(card.getCardId()) + ", '" + date + "', 0, 0, 0)";
    sql = const_cast<char*>(str.data());
    if (!insert(sql))
        return false;

    if (card.getType()) {
        str = "update card  set type = 1 where id = " + _general->toStr(card.getCardId());
        sql = const_cast<char*>(str.data());
        mysql_query(&mysql, sql);
    }
    str = "update member  set card_num = 1 where id = " + _general->toStr(toSetIdList[toSetIndex-1]);
    sql = const_cast<char*>(str.data());
    mysql_query(&mysql, sql);

    mysql_close(&mysql);
    return true;
}

Storage::~Storage()
{
    instance_ = NULL;
}

void initDB() {
    // 连接数据库
    connectMysql();

    /*
     * 如果数据库中 member表为空，则新建一个编号为0的用户，
     * 该用户无意义，仅用于Debug。
     */
    sql = "select * from member";
    query(sql);
    if (!(row = mysql_fetch_row(res)))
    {
        sql = "insert into  member (ID, NAME, ADDRESS, JOB, CARD_NUM) value (0, 'testuser', 'address', 'job', -1)";
        if (mysql_query(&mysql, sql) != 0) {
            cerr << "mysql_query: " << mysql_error(&mysql) << endl;
            mysql_close(&mysql);
        }
    }

    /*
     * 找出当前数据库Member表最大的编号，
     * 以确定新建会员时的编号。
     */
    sql = "select max(id) from member";
    query(sql);
    int max_num = 0;
    while (row = mysql_fetch_row(res))
    {
        max_num = _general->toInt(row[0]);
    }
    max_member_id = max_num+1;

    /*
     * 找出当前数据库Card表最大的编号，
     * 以确定新建会员卡时的编号。
     */
    sql = "select * from card";
    query(sql);
    if (!(row = mysql_fetch_row(res))) {
        sql = "insert into  card (ID, DATE, TIMES, PRICE, TYPE) value (0, '2000-01-01', 0, 0, -1)";
        if (mysql_query(&mysql, sql) != 0) {
            cerr << "mysql_query: " << mysql_error(&mysql) << endl;
            mysql_close(&mysql);
        }
    }

    /*
     * 同上 max_member_id
     */
    sql = "select max(id) from card";
    query(sql);
    max_num = 0;
    while (row = mysql_fetch_row(res))
    {
        max_num = general->toInt(row[0]);
    }
    max_card_id = max_num+1;

    mysql_close(&mysql);
}